package stock

import (
	"context"
	"encoding/json"
	// "fmt"
	"strconv"

	"mall/common/resultx"
	"mall/service/backend/common/i18n"
	"mall/service/product/rpc/internal/svc"
	"mall/service/product/rpc/types/product"

	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

const (
  luaSubtractStockRevertScript = `
if (ARGV[1] and ARGV[1] ~= "") then
  local json = cjson.decode(ARGV[1])
  local breakFlag = false
  for k, v in pairs(json) do
    local frozen = tonumber(redis.call('GET', v.frozen_key))
    local quantity = tonumber(v.quantity)
    if quantity > frozen then
      breakFlag = true
      break
    end
  end
  if breakFlag then
    return 0
  else
    for k, v in pairs(json) do
      local quantity = tonumber(v.quantity)
      redis.call('DECRBY', v.frozen_key, quantity)
    end
  end
  return 1
end
return 0
`
)

type SubtractStockRevertLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewSubtractStockRevertLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubtractStockRevertLogic {
	return &SubtractStockRevertLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *SubtractStockRevertLogic) SubtractStockRevert(
	in *product.CheckAndSubtractStockReq,
) (*product.BaseMsg, error) {
	// logrus.Info(fmt.Sprintf("SubtractStockRevert CheckAndSubtractStockReq : %+v ", in))

	if len(in.Data) > 0 {
		var items []*StockItem
		var keys []string
		for _, v := range in.Data {
			frozenKey := getStockFrozenKey(v.Id)
			items = append(items, &StockItem{
				FrozenKey: frozenKey,
				Quantity:  strconv.FormatInt(int64(v.Stock), 10),
			})
			keys = append(keys, frozenKey)
		}

		payload, err := json.Marshal(items)
		if err != nil {
			// logrus.Info(fmt.Sprintf("SubtractStockRevert json.Marshal err : %+v ", err))
			logx.Errorw("SubtractStockRevert json.Marshal err", logx.Field("detail", err.Error()))
			return nil, resultx.StatusError(resultx.PRODUCT_VARIATION_STOCK_VALIDATE_FAIL, "")
		}

		val, err := l.svcCtx.BizRedis.EvalCtx(l.ctx, luaSubtractStockRevertScript, keys, payload)
		if err != nil {
			// logrus.Info(fmt.Sprintf("SubtractStockRevert err : %+v ", err))
			logx.Errorw("SubtractStockRevert err", logx.Field("detail", err.Error()))
			// ERR Error running script (call to f_b6388380760ed39e90b575f7e665ab489275bf3a): @user_script:19: @user_script: 19: Lua redis() command arguments must be strings or integers
			// CROSSSLOT Keys in request don't hash to the same slot
			return nil, resultx.StatusError(resultx.PRODUCT_VARIATION_STOCK_INVALID, "")
		}

		if i, ok := val.(int64); ok && i == 1 {
			return &product.BaseMsg{
				Msg: i18n.UpdateSuccess,
			}, nil
		}

		return nil, resultx.StatusError(resultx.PRODUCT_VARIATION_STOCK_INVALID, "")
	}

	return &product.BaseMsg{}, nil
}
